//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.ctrip.corp.obt.shard.datasource;


import com.ctrip.corp.obt.generic.core.context.TenantContext;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import com.ctrip.corp.obt.shard.context.DataShardContext;
import com.ctrip.corp.obt.shard.exception.ShardException;
import com.ctrip.corp.obt.shard.holder.ShardSourceHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.Map;
import java.util.Optional;

import static com.ctrip.corp.obt.generic.constants.GenericConstants.DEFAULT;

/**
 * @author marco.zheng
 * @version 1.0
 * @date 2022/01/14
 * @description 动态路由数据源
 * @see
 * @since 1.0
 */
@Slf4j
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {

    public static DynamicRoutingDataSource create(Object defaultDataSource, Map<Object, Object> dataSourceMap) {
        DynamicRoutingDataSource dynamicDataSource = new DynamicRoutingDataSource();
        dynamicDataSource.setTargetDataSources(dataSourceMap);
        dynamicDataSource.setDefaultTargetDataSource(defaultDataSource);
        return dynamicDataSource;
    }

    @Override
    protected Object determineCurrentLookupKey() {
        String lookupKey;
        // shardModel注解选择数据源lookupKey（也就是tenant_id）
        if (StringUtils.isNotBlank(DataShardContext.getDBShardSource())) {
            lookupKey = DataShardContext.getDBShardSource();
        } else {
            lookupKey = Optional.ofNullable(TenantContext.getTenantId()).orElse(DEFAULT);
        }
        DataSource dataSource = super.getResolvedDataSources().get(lookupKey);
        log.info("DynamicRoutingDataSource tenantId: {}, lookupKey: {}, shardMode:{}", TenantContext.getTenantId(),
            lookupKey, DataShardContext.getDBShardSource());
        if (null == dataSource) {
            throw new ShardException("No datasource found for lookup key: " + lookupKey);
        }
        return lookupKey;
    }

    @Override
    public DataSource determineTargetDataSource() {
        return super.determineTargetDataSource();
    }
}
